#!python
import os
import struct
from Crypto.Cipher import ARC4
import glob
import time
#import pwgen
import hashlib
from gevent.pywsgi import format_date_time
import mimetypes
from baidu_pcs_server import guess_type
import base64
import uuid
import shutil
import ConfigParser
import sys
import sqlite3

key="27Dvduoa9eQ1PHu1EfVGM36ZYMQ70eRk"
identity = 0xffeeddcc

def md5(d):
    h=hashlib.md5()
    h.update(d)
    return h.hexdigest()

def rc4(key, data):
    a=ARC4.new(key)
    return a.encrypt(data)

def encrypt(src,dst):
    if not os.path.exists(src):
        raise OSError("%s not exists")
    fout=open(dst,"wb")
    fin = open(src,"rb")
    fout.write(struct.pack("!L", identity))
    fn = os.path.basename(src).decode("gbk").encode("utf-8")
    fn_e = base64.b64encode(fn)
    fn_w = fn_e + (chr(0x00) * (1024 - len(fn_e)))
    fout.write(fn_w)
    fout.write(rc4(key,fin.read(4096)))
    fend = os.path.getsize(src) - 4096
    remain = fend - 4096
    while remain > 0:
        if remain < 4096:
            data = fin.read(remain)
        else:
            data = fin.read(4096)
        fout.write(data)
        remain -= len(data)
    fout.write(rc4(key,fin.read(4096))) 
    fin.close()
    fout.close()
    
def init_db():
    conn = sqlite3.connect(db_name)
    cur = conn.cursor()
    try:
        cur.execute("select count(*) from info")
        cur.fetchall()
    except:
        cur.execute("""create table info(id integer primary key autoincrement,
            current_name text,
            origin_name text,
            content_type text,
            content_length int,
            last_modified text,
            etag text,
            head_times int
            )
            """)
            
    conn.commit()    
    cur.close()
    conn.close()
    
def write_info(current_name, origin_name, content_type, content_length, last_modified, etag):
    conn = sqlite3.connect(db_name)
    cur = conn.cursor()
    sql = """insert into info(current_name, origin_name, content_type, content_length, last_modified, etag)
                values('%s','%s', '%s', '%s', '%s', '%s')""" % (current_name, origin_name, content_type, content_length, last_modified, etag)
    cur.execute(sql)
    conn.commit()
    cur.close()
    conn.close()
    
def get_info(current_name):
    conn = sqlite3.connect(db_name)
    cur = conn.cursor()
    cur.execute("select current_name, origin_name, content_type, content_length, last_modified, etag from info where current_name = '%s'" % current_name)
    res = cur.fetchall()
    cur.close()
    conn.close()
    return res
    
if __name__ == "__main__":
    extensions=["*.mp4","*.m4a","*.rmvb","*.rm","*.3gp","*.mkv"]
    src_dir="e:/share/"
    dst_dir="e:/share/e/"
    info_root="e:/share/i/"
    configfile="server.cfg"
    
    db_name = "info.db"
    init_db()
    
    for i in range(1, len(sys.argv)):
        if sys.argv[i] == "-c":
            configfile = sys.argv[i+1]
        if sys.argv[i] == "-h":
            print "Usage: %s -c config\n%s -h" % (sys.argv[0], sys.argv[0])
            sys.exit(0)
            
    cfg = ConfigParser.ConfigParser()
    cfg.read(configfile)

    if cfg.has_section("server"):
        if cfg.has_option("server","www_root"):
            dst_dir = cfg.get("server","www_root")
        if cfg.has_option("server","info_root"):
            info_root= cfg.get("server","info_root")
        if cfg.has_option("server","video_src"):
            src_dir=cfg.get("server","video_src")

        if cfg.has_option("server","key"):
            key=cfg.get("server","key")

        if cfg.has_option("server","exts"):
            exts=cfg.get("server","exts")
            extensions=exts.split(",")
        if cfg.has_option("server","id"):
            identity = cfg.get("server","id")
            identity = int(identity,16)
        url = cfg.get("server", "url")    
    #for f in glob.glob("%s*_del" % src_dir):
    #    shutil.move(f,f.replace("_del",""))
    #print cfg.items("server")
    #print "id: 0x%x" % identity
    #print src_dir,dst_dir,info_root,key
    #print extensions
    #sys.exit(0)
    while True:
        for ext in extensions:
            sources = glob.glob(os.path.join(src_dir, ext))
            for f in sources:
                #dst_n="%s%s%s" % (
                #        pwgen.pwgen(5,no_symbols=True),
                #        time.strftime("%Y%m%d%H%M%S", time.localtime()),
                #        ext.replace("*",''))
                dst_n = md5(os.path.basename(f))[:20].upper()
                dst_fname=os.path.join(dst_dir, dst_n)
                dst_fname += ext.replace("*",'')
                if os.path.exists(dst_fname):
                    if os.path.getsize(dst_fname) - os.path.getsize(f) == 4:
                        continue
                encrypt(f, dst_fname)
                current_name = os.path.basename(dst_fname)
                #info_f = os.path.join(info_root, os.path.basename(dst_fname))
                #info_f += ".txt"
                r = get_info(current_name)
                if not r:
                    size=os.path.getsize(dst_fname)
                    mtime=os.path.getmtime(dst_fname)
                    ftype = guess_type(dst_fname)
                    etag = uuid.uuid1()
                    origin_name = base64.b64encode(os.path.basename(f))
                    write_info(current_name,origin_name, ftype, size, 
                            format_date_time(mtime), '"%s"' % etag)
                #fp=open(info_f,"w")

                #fp.write("Last-Modified:%s\n" % format_date_time(mtime))
                #fp.write("Content-Length:%d\n" % size)
                #fp.write("Content-Type:%s\n" % ftype)
                #fp.write('ETag:"%s"\n' % uuid.uuid1())
                #fp.write("Origin-Name:%s\n" % 
                #        base64.b64encode(os.path.basename(f)))
                #fp.write("Origin-Url:%s\n" % ( "%s%s" % (url, os.path.basename(dst_fname)), ))        
                #fp.close()
                shutil.move(f,f + "_del")
                print f
        time.sleep(120)
